package com.ayf.payment.game.api.service.sign.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.channel.zhifuyun.ZhiFuYunMerchantUtil;
import com.ayf.payment.game.api.channel.zhifuyun.req.ZFYAccountCreateReq;
import com.ayf.payment.game.api.channel.zhifuyun.req.ZFYChangeBankAccountReq;
import com.ayf.payment.game.api.channel.zhifuyun.req.ZFYQueryAccountStateReq;
import com.ayf.payment.game.api.channel.zhifuyun.res.ZFYAccountCreateRes;
import com.ayf.payment.game.api.channel.zhifuyun.res.ZFYChangeBankAccountRes;
import com.ayf.payment.game.api.channel.zhifuyun.res.ZFYQueryAccountStateRes;
import com.ayf.payment.game.api.config.SystemInitialization;
import com.ayf.payment.game.api.dto.MerchantDTO;
import com.ayf.payment.game.api.dto.ayb.SignPayProductDTO;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.dto.sign.*;
import com.ayf.payment.game.api.entity.Merchant;
import com.ayf.payment.game.api.entity.MerchantBank;
import com.ayf.payment.game.api.exception.NullSetException;
import com.ayf.payment.game.api.exception.ParameterException;
import com.ayf.payment.game.api.exception.ParameterListException;
import com.ayf.payment.game.api.service.MerchantBankService;
import com.ayf.payment.game.api.service.MerchantService;
import com.ayf.payment.game.api.service.SignPayProductService;
import com.ayf.payment.game.api.utils.JsonUtils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.ayf.payment.game.api.utils.ValidateUtil;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * @Author: zh-liang
 * @Date: 2022-08-16 15:55
 */
@Component("merchantTwoZFYSignHandler")
public class MerchantTwoZFYSignHandlerImpl implements MerchantTwoSignHandler {
    @Resource
    public SystemInitialization systemInitialization;
    @Resource
    private MerchantService merchantService;
    @Resource
    private MerchantBankService merchantBankService;

    @Resource
    private SignPayProductService signPayProductService;

    @Override
    public MerchantTwoApplyResDTO merchantTwoApply(MerchantTwoApplyReqDTO reqDTO, PaymentChannelDTO paymentChannelDTO) {
        String traceId = SnowFlakeUtils.getTraceId();
        Merchant merchant = new Merchant();
        merchant.setId(reqDTO.getMerchantId());
        MerchantDTO merchantDTO = merchantService.selectOne(merchant);
        MerchantBank merchantBank = merchantBankService.getMerchantBankByMid(reqDTO.getMerchantId());
        SignPayProductDTO signPayProduct = signPayProductService.getByMerchantIdAndPayCode(merchantDTO.getId(), paymentChannelDTO.getCode());
        ValidateUtil.businessValidate(signPayProduct == null || signPayProduct.getCountSignPayProduct() == 0, "已绑定，请勿重复操作");
        checkParameter(merchantDTO, merchantBank);

        ZFYAccountCreateReq req = new ZFYAccountCreateReq();
        req.setTraceId(traceId);
        req.setThirdUserID(String.valueOf(merchantDTO.getId()));
        req.setUserName(merchantBank.getAccountName());
        req.setIdentificationCard(merchantDTO.getIdCard());
        req.setMobile(merchantBank.getBankPhone());
        req.setBankName(merchantBank.getBankName());
        req.setBankAccount(merchantBank.getCardNo());
        ZFYAccountCreateRes res = ZhiFuYunMerchantUtil.accountCreate(req, paymentChannelDTO);
        if (!res.isSuccess()) {
            throw new NullSetException(res.getFailMsg());
        }
        SignPayProductDTO payProductDTO = new SignPayProductDTO();
        payProductDTO.setChannelMerchantId(res.getUniqueId());
        payProductDTO.setMerchantId(merchantDTO.getId());
        payProductDTO.setPayCode("ZFYFZ");
        payProductDTO.setApplyInfo(JsonUtils.toJson(req));
        payProductDTO.setApplyStatus(1);
        signPayProductService.insertSignPayProduct2(payProductDTO);
        return null;
    }

    @Override
    public MerchantTwoSelectResDTO merchantTwoSelect(MerchantTwoSelectReqDTO reqDTO, PaymentChannelDTO paymentChannelDTO) {
        String traceId = SnowFlakeUtils.getTraceId();
        MerchantTwoSelectResDTO res = new MerchantTwoSelectResDTO();
        res.setApplyStatus(1);
        SignPayProductDTO signPayProduct = signPayProductService.getByMerchantIdAndPayCode(reqDTO.getMerchantId(), paymentChannelDTO.getCode());
        ZFYQueryAccountStateReq req = new ZFYQueryAccountStateReq();
        req.setTraceId(traceId);
        req.setThirdUserID(String.valueOf(reqDTO.getMerchantId()));
        ZFYQueryAccountStateRes queryRes = ZhiFuYunMerchantUtil.queryAccountState(req, paymentChannelDTO);
        if (!queryRes.isSuccess()) {
            throw new NullSetException(queryRes.getFailMsg());
        }
        SignPayProductDTO payProductDTO = new SignPayProductDTO();
        String status = queryRes.getStatus();
        if (signPayProduct.getApplyStatus() != 2) {
            if ("2".equals(status)) {
                payProductDTO.setApplyStatus(-1);
                res.setApplyStatus(-1);
            } else if ("1".equals(status)||"3".equals(status)) {
                payProductDTO.setApplyStatus(2);
                res.setApplyStatus(2);
            } else {
                payProductDTO.setApplyStatus(1);
            }
        }
        if (signPayProduct.getUpdateStatus() == 1) {
            if ("2".equals(status)) {
                payProductDTO.setUpdateStatus(-1);
            } else if ("1".equals(status)||"3".equals(status)) {
                payProductDTO.setUpdateStatus(2);
            } else {
                payProductDTO.setUpdateStatus(1);
            }
        }
        if (payProductDTO.getUpdateStatus() != null || payProductDTO.getApplyStatus() != null) {
            payProductDTO.setFailMsg(queryRes.getFailMsg());
            payProductDTO.setId(signPayProduct.getId());
            signPayProductService.updateAyfSignPayProductById(payProductDTO);
        }
        return res;
    }

    @Override
    public MerchantTwoUpdateResDTO merchantTwoUpdate(MerchantTwoUpdateReqDTO reqDTO, PaymentChannelDTO paymentChannelDTO) {
        String traceId = SnowFlakeUtils.getTraceId();
        Merchant merchant = new Merchant();
        merchant.setId(reqDTO.getMerchantId());
        MerchantDTO merchantDTO = merchantService.selectOne(merchant);
        MerchantBank merchantBank = merchantBankService.getMerchantBankByMid(reqDTO.getMerchantId());
        SignPayProductDTO signPayProduct = signPayProductService.getByMerchantIdAndPayCode(merchantDTO.getId(), paymentChannelDTO.getCode());
        if (signPayProduct == null) {
            throw new ParameterException("请先进行二级账户申请");
        }
        checkParameter(merchantDTO, merchantBank);
        ZFYChangeBankAccountReq req = new ZFYChangeBankAccountReq();
        req.setTraceId(traceId);
        req.setThirdUserID(String.valueOf(merchantDTO.getId()));
        req.setUserName(merchantBank.getAccountName());
        req.setIdentificationCard(merchantDTO.getIdCard());
        req.setMobile(merchantBank.getBankPhone());
        req.setBankName(merchantBank.getBankName());
        req.setBankAccount(merchantBank.getCardNo());
        ZFYChangeBankAccountRes res = ZhiFuYunMerchantUtil.changeBankAccount(req, paymentChannelDTO);
        if (!res.isSuccess()) {
            throw new NullSetException(res.getFailMsg());
        }
        SignPayProductDTO payProductDTO = new SignPayProductDTO();
        payProductDTO.setId(signPayProduct.getId());
        payProductDTO.setMerchantId(merchantDTO.getId());
        payProductDTO.setUpdateStatus(1);
        payProductDTO.setFailMsg("-");
        if (signPayProduct.getApplyStatus() != null && signPayProduct.getApplyStatus() != 2) {
            payProductDTO.setApplyStatus(1);
        }
        payProductDTO.setApplyInfo(JSONObject.toJSONString(req));
        signPayProductService.updateAyfSignPayProductById(payProductDTO);
        return null;
    }

    @Override
    public MerchantTwoUpdateSuperResDTO merchantTwoUpdateSuper(MerchantTwoUpdateSuperReqDTO reqDTO, PaymentChannelDTO paymentChannelDTO) {
        return null;
    }

    private void checkParameter(MerchantDTO dto, MerchantBank merchantBank) throws ParameterException {
        List<String> msg = new ArrayList<>();
        if (StrUtil.isEmpty(merchantBank.getBankPhone())) {
            msg.add("银行预留手机号 不能为空");
        }
        if (StrUtil.isEmpty(merchantBank.getAccountName())) {
            msg.add("收款人 不能为空");
        }
        if (StrUtil.isEmpty(merchantBank.getCardNo())) {
            msg.add("银行账号 不能为空");
        }
        if (StrUtil.isEmpty(merchantBank.getBankName())) {
            msg.add("开户银行 不能为空");
        }
        if (StringUtils.isEmpty(dto.getIdCard())) {
            msg.add("身份证号 不能为空");
        }
        if (StringUtils.isNotBlank(dto.getIdCard()) && !IdcardUtil.isValidCard(dto.getIdCard())) {
            msg.add("身份证号 格式错误");
        }
        if (CollUtil.isNotEmpty(msg)) {
            throw new ParameterListException(msg);
        }
    }

    @Override
    public boolean merchantTwoApplyAsyncExec(MerchantTwoApplyAsyncReqDTO reqDTO, PaymentChannelDTO channel) {
        LinkedHashMap<String, Object> data = reqDTO.getData();
        String sign = (String) data.get("Sign");
        Integer UserId = Integer.valueOf((String) data.get("UserId"));
        String status = (String) data.get("Status");
        String Msg = (String) data.get("Msg");
        SignPayProductDTO dbSignPayProductDTO = signPayProductService.getByMerchantIdAndPayCode(UserId, channel.getCode());
        if (dbSignPayProductDTO == null) {
            LogPortal.info("{} 支付云-商户申请-异步通知 商户{}不存在", reqDTO.getTraceId(),UserId);
            return false;
        }
        data.remove("Sign");
        boolean validaSign = ZhiFuYunMerchantUtil.validaSign(reqDTO.getTraceId(), data, channel.getChannelKey(), sign);
        if (!validaSign) {
            LogPortal.info("{} 支付云-商户申请-异步通知 验签失败，不进行后续操作", reqDTO.getTraceId());
            return false;
        }
        SignPayProductDTO payProductDTO = new SignPayProductDTO();
        if (dbSignPayProductDTO.getApplyStatus() != 2) {
            if ("2".equals(status)) {
                payProductDTO.setApplyStatus(-1);
            } else if ("1".equals(status)||"3".equals(status)) {
                payProductDTO.setApplyStatus(2);
            } else {
                payProductDTO.setApplyStatus(1);
            }
        }
        if (dbSignPayProductDTO.getUpdateStatus() == 1) {
            if ("2".equals(status)) {
                payProductDTO.setUpdateStatus(-1);
            } else if ("1".equals(status)||"3".equals(status)) {
                payProductDTO.setUpdateStatus(2);
            } else {
                payProductDTO.setUpdateStatus(1);
            }
        }
        if (payProductDTO.getUpdateStatus() != null || payProductDTO.getApplyStatus() != null) {
            payProductDTO.setFailMsg(Msg);
            payProductDTO.setId(dbSignPayProductDTO.getId());
            signPayProductService.updateAyfSignPayProductById(payProductDTO);
        }
        return true;
    }
}
